package com.wangdong.wdutils.utils;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.UnderlineSpan;
import android.util.Base64;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author luyz
 * 字符串 工具类
 */
public class DLStringUtil {
	
	public static final String EMPTY = "";
    public static final int INDEX_NOT_FOUND = -1;
    public static final String[] EMPTY_STRING_ARRAY = new String[0];

    private DLStringUtil() {
        /* cannot be instantiated */
        throw new UnsupportedOperationException("cannot be instantiated");
    }

    /**
     * is null or its length is 0 or it is made by space
     * 
     * <pre>
     * isBlank(null) = true;
     * isBlank(&quot;&quot;) = true;
     * isBlank(&quot;  &quot;) = true;
     * isBlank(&quot;a&quot;) = false;
     * isBlank(&quot;a &quot;) = false;
     * isBlank(&quot; a&quot;) = false;
     * isBlank(&quot;a b&quot;) = false;
     * </pre>
     * 
     * @param str String
     * @return if string is null or its size is 0 or it is made by space, return true, else return false.
     */
    public static boolean isBlank(String str) {
        return (str == null || str.trim().length() == 0);
    }
    
    /**
     * 判断字符是否为空
     * <pre>
     * isEmpty(null) = true;
     * isEmpty(&quot;&quot;) = true;
     * isEmpty(&quot;  &quot;) = false;
     * </pre>
     * @param cs CharSequence
     * @return if string is null or its size is 0, return true, else return false.
     */
    public static boolean isEmpty(String cs) {
        return cs == null || cs.length() == 0;
    }

    /**
     * 判断字符是否不是空
     *
     * @param s String
     * @return if string not is null or its size not is 0, return true, else return false.
     */
    public static boolean notEmpty(String s) {
        return s != null && !"".equals(s) && !"null".equals(s);
    }
    
    /**
     * 获取字符串长度
     * 
     * <pre>
     * length(null) = 0;
     * length(\"\") = 0;
     * length(\"abc\") = 3;
     * </pre>
     * 
     * @param str CharSequence
     * @return if str is null or empty, return 0, else return {@link CharSequence#length()}.
     */
    public static int length(CharSequence str) {
        return str == null ? 0 : str.length();
    }
    
    /**
     * 首字母 大写
     * 
     * <pre>
     * capitalizeFirstLetter(null)     =   null;
     * capitalizeFirstLetter("")       =   "";
     * capitalizeFirstLetter("2ab")    =   "2ab"
     * capitalizeFirstLetter("a")      =   "A"
     * capitalizeFirstLetter("ab")     =   "Ab"
     * capitalizeFirstLetter("Abc")    =   "Abc"
     * </pre>
     * 
     * @param str String
     * @return String
     */
    public static String capitalizeFirstLetter(String str) {
        if (isEmpty(str)) {
            return str;
        }

        char c = str.charAt(0);
        return (!Character.isLetter(c) || Character.isUpperCase(c)) ? str : new StringBuilder(str.length())
                .append(Character.toUpperCase(c)).append(str.substring(1)).toString();
    }
    
    /**
     * encoded in utf-8  url编码
     * 
     * <pre>
     * utf8Encode(null)        =   null
     * utf8Encode("")          =   "";
     * utf8Encode("aa")        =   "aa";
     * utf8Encode("啊啊啊啊")   = "%E5%95%8A%E5%95%8A%E5%95%8A%E5%95%8A";
     * </pre>
     * 
     * @param str String
     * @return String
     */
    public static String utf8Encode(String str) {
        if (!isEmpty(str) && str.getBytes().length != str.length()) {
            try {
                return URLEncoder.encode(str, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("UnsupportedEncodingException occurred. ", e);
            }
        }
        return str;
    }

    /**
     * get innerHtml from href
     * 
     * <pre>
     * getHrefInnerHtml(null)                                  = ""
     * getHrefInnerHtml("")                                    = ""
     * getHrefInnerHtml("mp3")                                 = "mp3";
     * getHrefInnerHtml("&lt;a innerHtml&lt;/a&gt;")                    = "&lt;a innerHtml&lt;/a&gt;";
     * getHrefInnerHtml("&lt;a&gt;innerHtml&lt;/a&gt;")                    = "innerHtml";
     * getHrefInnerHtml("&lt;a&lt;a&gt;innerHtml&lt;/a&gt;")                    = "innerHtml";
     * getHrefInnerHtml("&lt;a href="baidu.com"&gt;innerHtml&lt;/a&gt;")               = "innerHtml";
     * getHrefInnerHtml("&lt;a href="baidu.com" title="baidu"&gt;innerHtml&lt;/a&gt;") = "innerHtml";
     * getHrefInnerHtml("   &lt;a&gt;innerHtml&lt;/a&gt;  ")                           = "innerHtml";
     * getHrefInnerHtml("&lt;a&gt;innerHtml&lt;/a&gt;&lt;/a&gt;")                      = "innerHtml";
     * getHrefInnerHtml("jack&lt;a&gt;innerHtml&lt;/a&gt;&lt;/a&gt;")                  = "innerHtml";
     * getHrefInnerHtml("&lt;a&gt;innerHtml1&lt;/a&gt;&lt;a&gt;innerHtml2&lt;/a&gt;")        = "innerHtml2";
     * </pre>
     * 
     * @param href String
     * @return <ul>
     *         <li>if href is null, return ""</li>
     *         <li>if not match regx, return source</li>
     *         <li>return the last string that match regx</li>
     *         </ul>
     */
    public static String getHrefInnerHtml(String href) {
        if (isEmpty(href)) {
            return "";
        }

        String hrefReg = ".*<[\\s]*a[\\s]*.*>(.+?)<[\\s]*/a[\\s]*>.*";
        Pattern hrefPattern = Pattern.compile(hrefReg, Pattern.CASE_INSENSITIVE);
        Matcher hrefMatcher = hrefPattern.matcher(href);
        if (hrefMatcher.matches()) {
            return hrefMatcher.group(1);
        }
        return href;
    }

    /**
     * process special char in html
     * 
     * <pre>
     * htmlEscapeCharsToString(null) = null;
     * htmlEscapeCharsToString("") = "";
     * htmlEscapeCharsToString("mp3") = "mp3";
     * htmlEscapeCharsToString("mp3&lt;") = "mp3";
     * htmlEscapeCharsToString("mp3&gt;") = "mp3";
     * htmlEscapeCharsToString("mp3&amp;mp4") = "mp3/mp4";
     * htmlEscapeCharsToString("mp3&quot;mp4") = "mp3/mp4";
     * htmlEscapeCharsToString("mp3&lt;&gt;&amp;&quot;mp4") = "mp3/mp4";
     * </pre>
     * 
     * @param source String
     * @return String
     */
    public static String htmlEscapeCharsToString(String source) {
        return DLStringUtil.isEmpty(source) ? source : source.replaceAll("&lt;", "<").replaceAll("&gt;", ">")
                .replaceAll("&amp;", "&").replaceAll("&quot;", "\"");
    }
    
    /**
     * 从左侧开始截取str返回separator前面的字符串(不包含separator)
     *
     * @param str String
     * @param separator String
     * @return String
     */
    public static String substringBefore(String str, String separator) {
        if (isEmpty(str) || separator == null) {
            return str;
        }
        if (separator.length() == 0) {
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return str;
        }
        return str.substring(0, pos);
    }

    /**
     * 从左侧开始截取str返回separator后面的字符串(不包含separator)
     *
     * @param str String
     * @param separator String
     * @return String
     */
    public static String substringAfter(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        }
        if (separator == null) {
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return EMPTY;
        }
        return str.substring(pos + separator.length());
    }

    /**
     * 从右侧开始截取str返回separator前面的字符串(不包含separator)
     *
     * @param str String
     * @param separator String
     * @return String
     */
    public static String substringBeforeLast(String str, String separator) {
        if (isEmpty(str) || isEmpty(separator)) {
            return str;
        }
        int pos = str.lastIndexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return str;
        }
        return str.substring(0, pos);
    }

    /**
     * 从右侧开始截取str返回separator后面的字符串(不包含separator)
     *
     * @param str String
     * @param separator String
     * @return String
     */
    public static String substringAfterLast(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        }
        if (isEmpty(separator)) {
            return EMPTY;
        }
        int pos = str.lastIndexOf(separator);
        if (pos == INDEX_NOT_FOUND || pos == (str.length() - separator.length())) {
            return EMPTY;
        }
        return str.substring(pos + separator.length());
    }

    /**
     * 返回两个tag字符串在str中间的字符串,如果tag在str中只有一个返回null
     *
     * @param str String
     * @param tag String
     * @return String
     */
    public static String substringBetween(String str, String tag) {
        return substringBetween(str, tag, tag);
    }

    /**
     * 返回open和close字符串在str中间的字符串,如果没有返回null
     *
     * @param str   String
     * @param open String
     * @param close String
     * @return String
     */
    public static String substringBetween(String str, String open, String close) {
        if (str == null || open == null || close == null) {
            return null;
        }
        int start = str.indexOf(open);
        if (start != INDEX_NOT_FOUND) {
            int end = str.indexOf(close, start + open.length());
            if (end != INDEX_NOT_FOUND) {
                return str.substring(start + open.length(), end);
            }
        }
        return null;
    }

    /**
     * 返回open和close字符串在str中间的字符串的字符串数组,如果没有返回null
     *
     * @param str   String
     * @param open String
     * @param close String
     * @return String[]
     */
    public static String[] substringsBetween(String str, String open, String close) {
        if (str == null || isEmpty(open) || isEmpty(close)) {
            return null;
        }
        int strLen = str.length();
        if (strLen == 0) {
            return EMPTY_STRING_ARRAY;
        }
        int closeLen = close.length();
        int openLen = open.length();
        List<String> list = new ArrayList<String>();
        int pos = 0;
        while (pos < (strLen - closeLen)) {
            int start = str.indexOf(open, pos);
            if (start < 0) {
                break;
            }
            start += openLen;
            int end = str.indexOf(close, start);
            if (end < 0) {
                break;
            }
            list.add(str.substring(start, end));
            pos = end + closeLen;
        }
        if (list.isEmpty()) {
            return null;
        }
        return list.toArray(new String[list.size()]);
    }

    /**
     * 字符串转换字符串数组
     *
     * @param str String
     * @return String[]
     */
    public static String[] split(String str) {
        if (str == null || str.trim().equals(""))
            return null;
        // ‘,’作为分隔符
        StringTokenizer commaToker = new StringTokenizer(str, ", ");
        // commaToker.countTokens()分隔符的数量
        String[] result = new String[commaToker.countTokens()];
        int m = 0;
        // hasMoreTokens()是否还有分隔符
        while (commaToker.hasMoreTokens()) {
            // 翻译从当前位置到下一个分隔符的字符串
            result[m] = commaToker.nextToken();
            m++;
        }
        return result;
    }

    /**
     * 字符串转整形
     *
     * @param str String
     * @return int
     */
    public static int strToInt(String str) {
        int value;
        try {
            if (str.contains(".")) {
                str = str.substring(0, str.indexOf('.'));
            }
            value = Integer.parseInt(str.trim());
        } catch (NumberFormatException e) {
//        	DLLogUtil.printErrorMessage(e);
            value = -1;
        }
        return value;
    }

    /**
     * 字符串转布尔值
     * @param str String
     * @return boolean
     */
    public static boolean strToBoolean(String str){
    	boolean value = false;
    	
    	try{
    		value = Boolean.parseBoolean(str);
    	}catch(NumberFormatException e){
//    		DLLogUtil.printErrorMessage(e);
            value = false;
    	}
    	
    	return value;
    }

    /**
     * 字符串转长整形
     *
     * @param str String
     * @return long
     */
    public static long strToLong(String str) {
        long value;
        try {
            value = Long.valueOf(str);
        } catch (NumberFormatException e) {
//        	DLLogUtil.printErrorMessage(e);
            value = -1;
        }
        return value;
    }

    /**
     * 字符串转双精
     *
     * @param str String
     * @return double
     */
    public static double strToDouble(String str) {
        double value;
        try {
            value = Double.parseDouble(str);
        } catch (NumberFormatException e) {
//        	DLLogUtil.printErrorMessage(e);
            value = 0.0;
        }
        return value;
    }

    /**
     * 为文本添加下划线
     *
     * @param str String
     * @return SpannableString
     */
    public static SpannableString setTextUnderline(String str) {
        SpannableString spString = new SpannableString(str);
        spString.setSpan(new UnderlineSpan(), 0, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spString;
    }

    /**
     * 输入流转UTF-8编码
     *
     * @param is InputStream
     * @return StringBuffer  String
     * @throws IOException IOException
     */
    public static String toUTF8String(InputStream is) throws IOException {
        if (is == null)
            return null;
        StringBuffer sb = new StringBuffer();
        InputStreamReader isReader = new InputStreamReader(is, "UTF-8");
        BufferedReader br = new BufferedReader(isReader);
        String data = "";
        while ((data = br.readLine()) != null) {
            sb.append(data);
        }
        return sb.toString();
    }
    
    /**
	 * String 转 InputStream
	 * @param str String
	 * @return InputStream
	 */
	public static InputStream stringToInputStream(String str) {
		
		if (str == null) {
			return null;
		}
		ByteArrayInputStream result = null;
		try {
			result = new ByteArrayInputStream(str.getBytes());
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return result;

	}

    /**
     * String转UTF-8
     *
     * @param strContent String
     * @return String
     */
    public static String formatUTF8(String strContent) {
        try {
            return new String(strContent.getBytes("UTF-8"), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 判断是不是中文
     *
     * @param value String
     * @return boolean
     */
    public static boolean isChinese(String value) {
        String chinese = "[\u4e00-\u9fa5]"; // 匹配中文节字符
        if (value.matches(chinese)) {
            return true;
        }
        return false;
    }

    /**
     * 判断是不是英文
     *
     * @param value String
     * @return boolean
     */
    public static boolean isEnglish(String value) {
        String english = "[a-zA-Z]";// 匹配英文字符
        if (value.matches(english)) {
            return true;
        }
        return false;
    }

    /**
     * 验证一串字符串是否全为数字
     *
     * @param str String
     * @return boolean
     */
    public static boolean isNumber(String str) {
        String pattern = "[0-9]+";
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 判断是否是电话号码
     *
     * @param phone boolean
     * @return Boolean
     */
    public static Boolean isPhoneNumbers(String phone) {

        Pattern p1 = Pattern.compile("^((0?(1[3-9][0-9]))\\d{8})$");
        return p1.matcher(phone).matches();
    }

    /**
     * 判断是否为邮箱
     *
     * @param email String
     * @return boolean
     */
    public static boolean isEmail(String email) {
        String str = "^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(email);
        return m.matches();
    }

    public static String findChinese(String str) {
        String chinese = "[\u4e00-\u9fa5]";
        Pattern p = Pattern.compile(chinese);
        Matcher m = p.matcher(str);
        while (m.find()) {
            str += m.group().toString();
        }
        return str;
    }
    
    public static boolean isURL(String url){
    	if(DLStringUtil.notEmpty(url)){
    		if(url.startsWith("http://")){
    			return true;
    		}else if(url.startsWith("https://")){
                return true;
            }
    	}
    	return false;
    }
    
    /**  
     * bitmap 图片转成string  
     *   
     * @param bitmap   Bitmap
     * @return  String
     */  
    public static String convertBitmapToString(Bitmap bitmap)
    {  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream
        bitmap.compress(CompressFormat.PNG, 100, baos);
        byte[] appicon = baos.toByteArray();// 转为byte数组  
        return Base64.encodeToString(appicon, Base64.DEFAULT);
  
    }  
  
    /**  
     * string转成bitmap  
     *   
     * @param st   String
     * @return Bitmap
     */  
    public static Bitmap convertStringToBitmap(String st)
    {  
        // OutputStream out;  
        Bitmap bitmap = null;
        try  
        {  
            // out = new FileOutputStream("/sdcard/aa.jpg");  
            byte[] bitmapArray;  
            bitmapArray = Base64.decode(st, Base64.DEFAULT);
            bitmap =  
                    BitmapFactory.decodeByteArray(bitmapArray, 0,
                            bitmapArray.length);  
            // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  
            return bitmap;  
        }  
        catch (Exception e)
        {  
            return null;  
        }  
    }

    //检测支付密码
    public static boolean checkPaypwd(String pwd){
        boolean flag = true;

        if (equalStr(pwd)){
            return flag;
        }

        if (isOrderNumeric(pwd)){
            return flag;
        }

        if (isOrderNumeric_(pwd)){
            return flag;
        }

        return false;
    }

    //不能全是相同的数字或者字母（如：000000、111111、aaaaaa） 全部相同返回true
    public static boolean equalStr(String numOrStr){
        boolean flag = true;
        char str = numOrStr.charAt(0);
        for (int i = 0; i < numOrStr.length(); i++) {
            if (str != numOrStr.charAt(i)) {
                flag = false;
                break;
            }
        }
        return flag;
    }
    //不能是连续的数字--递增（如：123456、12345678）连续数字返回true
    public static boolean isOrderNumeric(String numOrStr){
        boolean flag = true;//如果全是连续数字返回true
        boolean isNumeric = true;//如果全是数字返回true
        for (int i = 0; i < numOrStr.length(); i++) {
            if (!Character.isDigit(numOrStr.charAt(i))) {
                isNumeric = false;
                break;
            }
        }
        if (isNumeric) {//如果全是数字则执行是否连续数字判断
            for (int i = 0; i < numOrStr.length(); i++) {
                if (i > 0) {//判断如123456
                    int num = Integer.parseInt(numOrStr.charAt(i)+"");
                    int num_ = Integer.parseInt(numOrStr.charAt(i-1)+"")+1;
                    if (num != num_) {
                        flag = false;
                        break;
                    }
                }
            }
        } else {
            flag = false;
        }
        return flag;
    }
    //不能是连续的数字--递减（如：987654、876543）连续数字返回true
    public static boolean isOrderNumeric_(String numOrStr){
        boolean flag = true;//如果全是连续数字返回true
        boolean isNumeric = true;//如果全是数字返回true
        for (int i = 0; i < numOrStr.length(); i++) {
            if (!Character.isDigit(numOrStr.charAt(i))) {
                isNumeric = false;
                break;
            }
        }
        if (isNumeric) {//如果全是数字则执行是否连续数字判断
            for (int i = 0; i < numOrStr.length(); i++) {
                if (i > 0) {//判断如654321
                    int num = Integer.parseInt(numOrStr.charAt(i)+"");
                    int num_ = Integer.parseInt(numOrStr.charAt(i-1)+"")-1;
                    if (num != num_) {
                        flag = false;
                        break;
                    }
                }
            }
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 保留小数点后2位
     * @param value 值
     * @return String
     */
    public static String retainDecimal2Point(String value){

        BigDecimal d = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP);
        return d.toString();
//        DecimalFormat df   =   new   DecimalFormat("#####0.00");
//        return df.format(Double.parseDouble(value));//返回的是String类型的数据
    }

    /**
     * 去除小数点后的0
     * @param s String
     * @return String
     */
    public static String cutPoint(String s){
        if(s.indexOf(".") > 0){
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }

    static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'A', 'B', 'C', 'D', 'E', 'F'};
    /**
     * byteArr转hexString
     * <p>例如：</p>
     * bytes2HexString(new byte[] { 0, (byte) 0xa8 }) returns 00A8
     *
     * @param bytes byte数组
     * @return 16进制大写字符串
     */
    public static String bytes2HexString(byte[] bytes) {
        char[] ret = new char[bytes.length << 1];
        for (int i = 0, j = 0; i < bytes.length; i++) {
            ret[j++] = hexDigits[bytes[i] >>> 4 & 0x0f];
            ret[j++] = hexDigits[bytes[i] & 0x0f];
        }
        return new String(ret);
    }

    /**
     * hexString转byteArr
     * <p>例如：</p>
     * hexString2Bytes("00A8") returns { 0, (byte) 0xA8 }
     *
     * @param hexString 十六进制字符串
     * @return 字节数组
     */
    public static byte[] hexString2Bytes(String hexString) {
        int len = hexString.length();
        if (len % 2 != 0) {
            throw new IllegalArgumentException("长度不是偶数");
        }
        char[] hexBytes = hexString.toUpperCase().toCharArray();
        byte[] ret = new byte[len >>> 1];
        for (int i = 0; i < len; i += 2) {
            ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1]));
        }
        return ret;
    }


    /**
     * hexChar转int
     *
     * @param hexChar hex单个字节
     * @return 0..15
     */
    private static int hex2Dec(char hexChar) {
        if (hexChar >= '0' && hexChar <= '9') {
            return hexChar - '0';
        } else if (hexChar >= 'A' && hexChar <= 'F') {
            return hexChar - 'A' + 10;
        } else {
            throw new IllegalArgumentException();
        }
    }
}
